# ui/version_dialogs.py - 完整功能版本
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import os
from pathlib import Path

from models.file_version import FileVersion
from utils.validation_utils import validate_version
from logger.logger import get_logger

class VersionDialogs:
    """版本相关对话框 - 完整功能版本"""
    
    def __init__(self, root, config, download_manager, auth_manager):
        self.root = root
        self.config = config
        self.download_manager = download_manager
        self.auth_manager = auth_manager
        self.logger = get_logger(config)
    
    def show_create_version_dialog(self, package_name: str, callback: callable = None):
        """显示创建版本对话框"""
        dialog = tk.Toplevel(self.root)
        dialog.title(f"新建版本 - {package_name}")
        dialog.geometry("500x400")
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 版本号
        ttk.Label(dialog, text="版本号:").pack(anchor=tk.W, pady=(10, 5), padx=10)
        version_var = tk.StringVar()
        version_entry = ttk.Entry(dialog, textvariable=version_var, width=50)
        version_entry.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        # 版本简述
        ttk.Label(dialog, text="版本简述:").pack(anchor=tk.W, pady=(0, 5), padx=10)
        brief_var = tk.StringVar()
        brief_entry = ttk.Entry(dialog, textvariable=brief_var, width=50)
        brief_entry.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        # 版本简介
        ttk.Label(dialog, text="版本简介:").pack(anchor=tk.W, pady=(0, 5), padx=10)
        description_text = tk.Text(dialog, height=6, width=50)
        description_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=(0, 10))
        
        # 文件选择
        file_frame = ttk.Frame(dialog)
        file_frame.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        file_var = tk.StringVar(value="未选择文件")
        ttk.Label(file_frame, textvariable=file_var).pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        file_path = None
        
        def select_file():
            nonlocal file_path
            filename = filedialog.askopenfilename(
                title="选择版本文件",
                filetypes=[("所有文件", "*.*")]
            )
            if filename:
                file_path = filename
                file_var.set(Path(filename).name)
        
        ttk.Button(file_frame, text="选择文件", command=select_file).pack(side=tk.RIGHT)
        
        # 协议确认
        agreement_var = tk.BooleanVar()
        agreement_check = ttk.Checkbutton(
            dialog, 
            text="我同意遵守相关协议（必须遵守法律法规，不得上传违法内容）",
            variable=agreement_var
        )
        agreement_check.pack(anchor=tk.W, padx=10, pady=(0, 10))
        
        # 按钮框架
        button_frame = ttk.Frame(dialog)
        button_frame.pack(fill=tk.X, padx=10, pady=10)
        
        def create_version():
            """创建版本"""
            # 验证输入
            version = version_var.get().strip()
            brief = brief_var.get().strip()
            description = description_text.get("1.0", tk.END).strip()
            
            if not version:
                messagebox.showwarning("警告", "请输入版本号")
                return
            
            if not validate_version(version):
                messagebox.showwarning("警告", "版本号格式不正确")
                return
            
            if not brief:
                messagebox.showwarning("警告", "请输入版本简述")
                return
            
            if not description:
                messagebox.showwarning("警告", "请输入版本简介")
                return
            
            if not file_path:
                messagebox.showwarning("警告", "请选择版本文件")
                return
            
            if not agreement_var.get():
                messagebox.showwarning("警告", "请同意相关协议")
                return
            
            # 检查文件大小（可选，根据需求）
            file_size = os.path.getsize(file_path)
            if file_size > 64 * 1024 * 1024:  # 64MB
                messagebox.showwarning("警告", "文件大小超过64MB限制")
                return
            
            # 验证权限
            if not self.auth_manager.has_upload_permission():
                password = self._ask_for_password()
                if not password:
                    return
                if not self.auth_manager.check_upload_permission(password):
                    messagebox.showerror("错误", "权限验证失败")
                    return
            
            # 创建版本对象
            version_obj = FileVersion(
                version=version,
                brief=brief,
                description=description
            )
            
            # 添加到包
            success = self.download_manager.add_version_to_package(
                package_name, version_obj, file_path
            )
            
            if success:
                messagebox.showinfo("成功", "版本创建成功")
                self.logger.info(f"版本创建成功: {package_name} {version}")
                dialog.destroy()
                if callback:
                    callback(True)
            else:
                messagebox.showerror("错误", "版本创建失败")
                self.logger.error(f"版本创建失败: {package_name} {version}")
        
        def cancel():
            dialog.destroy()
            if callback:
                callback(False)
        
        ttk.Button(button_frame, text="创建", command=create_version).pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(button_frame, text="取消", command=cancel).pack(side=tk.LEFT)
        
        # 绑定回车键
        dialog.bind('<Return>', lambda e: create_version())
        version_entry.focus()
    
    def show_edit_version_dialog(self, package_name: str, version: str, 
                               version_info: FileVersion, callback: callable = None):
        """显示编辑版本对话框"""
        dialog = tk.Toplevel(self.root)
        dialog.title(f"编辑版本 - {package_name} {version}")
        dialog.geometry("500x400")
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 版本简述
        ttk.Label(dialog, text="版本简述:").pack(anchor=tk.W, pady=(10, 5), padx=10)
        brief_var = tk.StringVar(value=version_info.brief)
        brief_entry = ttk.Entry(dialog, textvariable=brief_var, width=50)
        brief_entry.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        # 版本简介
        ttk.Label(dialog, text="版本简介:").pack(anchor=tk.W, pady=(0, 5), padx=10)
        description_text = tk.Text(dialog, height=8, width=50)
        description_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=(0, 10))
        description_text.insert("1.0", version_info.description)
        
        # 按钮框架
        button_frame = ttk.Frame(dialog)
        button_frame.pack(fill=tk.X, padx=10, pady=10)
        
        def update_version():
            """更新版本"""
            brief = brief_var.get().strip()
            description = description_text.get("1.0", tk.END).strip()
            
            if not brief:
                messagebox.showwarning("警告", "请输入版本简述")
                return
            
            if not description:
                messagebox.showwarning("警告", "请输入版本简介")
                return
            
            # 验证权限
            if not self.auth_manager.has_upload_permission():
                password = self._ask_for_password()
                if not password:
                    return
                if not self.auth_manager.check_upload_permission(password):
                    messagebox.showerror("错误", "权限验证失败")
                    return
            
            # 更新版本信息
            success = self.download_manager.update_version_info(
                package_name, version, brief, description
            )
            
            if success:
                messagebox.showinfo("成功", "版本信息更新成功")
                self.logger.info(f"版本更新成功: {package_name} {version}")
                dialog.destroy()
                if callback:
                    callback(True)
            else:
                messagebox.showerror("错误", "版本信息更新失败")
                self.logger.error(f"版本更新失败: {package_name} {version}")
        
        def delete_version():
            """删除版本"""
            if messagebox.askyesno("确认", f"确定要删除版本 {version} 吗？此操作不可恢复！"):
                # 这里需要实现删除版本的方法
                # 注意：删除版本需要同时删除服务器上的文件和相关记录
                messagebox.showinfo("提示", "删除版本功能待实现")
                self.logger.warning(f"尝试删除版本: {package_name} {version} (功能未实现)")
                # 暂时关闭对话框
                dialog.destroy()
                if callback:
                    callback(True)
        
        ttk.Button(button_frame, text="更改", command=update_version).pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(button_frame, text="删除", command=delete_version).pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(button_frame, text="取消", command=dialog.destroy).pack(side=tk.LEFT)
        
        # 绑定回车键
        dialog.bind('<Return>', lambda e: update_version())
        brief_entry.focus()
    
    def show_version_detail_dialog(self, package_name: str, version: str, 
                                 version_info: FileVersion, download_callback: callable = None):
        """显示版本详情对话框"""
        dialog = tk.Toplevel(self.root)
        dialog.title(f"版本详情 - {package_name} {version}")
        dialog.geometry("500x400")
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 版本信息框架
        info_frame = ttk.Frame(dialog)
        info_frame.pack(fill=tk.X, padx=10, pady=10)
        
        # 版本号
        ttk.Label(info_frame, text="版本号:", font=("Arial", 10, "bold")).pack(anchor=tk.W)
        ttk.Label(info_frame, text=version, font=("Arial", 10)).pack(anchor=tk.W, pady=(0, 10))
        
        # 版本简述
        ttk.Label(info_frame, text="版本简述:", font=("Arial", 10, "bold")).pack(anchor=tk.W)
        ttk.Label(info_frame, text=version_info.brief, wraplength=450).pack(anchor=tk.W, pady=(0, 10))
        
        # 版本简介
        ttk.Label(info_frame, text="版本简介:", font=("Arial", 10, "bold")).pack(anchor=tk.W)
        
        description_text = tk.Text(info_frame, height=8, width=50, wrap=tk.WORD)
        description_text.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        description_text.insert("1.0", version_info.description)
        description_text.config(state=tk.DISABLED)
        
        # 文件信息
        file_frame = ttk.Frame(dialog)
        file_frame.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        file_info = f"文件: {version_info.file_name} ({self.format_file_size(version_info.file_size)})"
        ttk.Label(file_frame, text=file_info, font=("Arial", 9)).pack(anchor=tk.W)
        
        ttk.Label(file_frame, text=f"上传时间: {version_info.upload_time}", font=("Arial", 9)).pack(anchor=tk.W)
        
        # 按钮框架
        button_frame = ttk.Frame(dialog)
        button_frame.pack(fill=tk.X, padx=10, pady=10)
        
        def download_version():
            """下载版本文件"""
            filename = filedialog.asksaveasfilename(
                title="保存文件",
                initialfile=version_info.file_name,
                defaultextension=".*"
            )
            if filename:
                if download_callback:
                    download_callback(package_name, version, filename)
                dialog.destroy()
        
        ttk.Button(
            button_frame,
            text="下载",
            command=download_version
        ).pack(side=tk.LEFT, padx=(0, 10))
        
        ttk.Button(
            button_frame,
            text="关闭",
            command=dialog.destroy
        ).pack(side=tk.LEFT)
    
    def _ask_for_password(self) -> str:
        """请求输入密码"""
        password = tk.simpledialog.askstring(
            "权限验证",
            "请输入管理员密码:",
            show='*',
            parent=self.root
        )
        return password
    
    def format_file_size(self, size_bytes: int) -> str:
        """格式化文件大小显示"""
        if not size_bytes:
            return "未知大小"
        
        try:
            size_bytes = int(size_bytes)
            if size_bytes == 0:
                return "0 B"
            
            units = ['B', 'KB', 'MB', 'GB']
            size = float(size_bytes)
            unit_index = 0
            
            while size >= 1024 and unit_index < len(units) - 1:
                size /= 1024
                unit_index += 1
            
            return f"{size:.1f} {units[unit_index]}"
        except (ValueError, TypeError):
            return "未知大小"